﻿#include "CMeasurePoint.h"
#include "CMeasurePoint.h"
#include <QDebug>
#include <QFileInfo>

CMeasurePoint::CMeasurePoint(const QString & sId, const QString & sName, const QString & sConfig, QObject * parent, EPointType type, const QString & unit)
	: CBaseNode(sId, sName, sConfig, parent),
	m_eType(type),
	m_sUnit(unit),
	m_eStatus(EPointQuality::enBad)
{
	m_bAlarmPoint = false;
	m_eNodeType = enMeasurePoint;
	m_sMappedAddr = "";
	initPoint();
	if(parent!=nullptr)
	((CBaseNode *)parent)->addChild(this);
}

CMeasurePoint::~CMeasurePoint()
{
	for (int i = 0; i < m_pVecBaseNode.size(); i++)
	{
		m_pVecBaseNode[i]->disposeNode(this);
	}
}

void CMeasurePoint::start()
{

}

void CMeasurePoint::stop() 
{

}

void CMeasurePoint::updateData() 
{
	for (CBaseNode *pNode : m_pVecBaseNode)
	{
		pNode->updateData();
	}
}

EPointType CMeasurePoint::getType() const 
{
	return m_eType;
}

EPointQuality CMeasurePoint::getStatus() const 
{
	return m_eStatus;
}

QString CMeasurePoint::getStatusInfo() const
{
	if (m_eStatus == EPointQuality::enGood)
	{
		return "Good";
	}
	else if (m_eStatus == EPointQuality::enBad)
	{
		return "Bad";
	}
	else if (m_eStatus == EPointQuality::enTimeOut)
	{
		return "TimeOut";
	}
	else if (m_eStatus == EPointQuality::enUncertain)
	{
		return "Uncertain";
	}
	return "Good";
}

QString CMeasurePoint::getUnit()  
{
	if (m_sUnit == "")
	{
		m_sUnit = "/";
	}
	return m_sUnit;
}

QVariant CMeasurePoint::getValue() const 
{
	QReadLocker locker(&m_rwLock);
	return m_vValue;
}

QString CMeasurePoint::getFileRef() const
{
	QReadLocker locker(&m_rwLock);
	return m_sFileRef;
}

QDateTime CMeasurePoint::getLastUpdateTime() const 
{
	return m_lastUpdateTime;
}

QString CMeasurePoint::getValType() const
{
	return m_sValType;
}

QString CMeasurePoint::getMappedAddr() const
{
	return m_sMappedAddr;
}

bool CMeasurePoint::getIsAlarmPoint()
{
	return m_bAlarmPoint;
}

void CMeasurePoint::addAssociated(CBaseNode* pNode)
{
	m_pVecBaseNode.push_back(pNode);
}

void CMeasurePoint::deleteAssociated(CBaseNode* pNode)
{
	for (int i = 0; i < m_pVecBaseNode.size(); i++)
	{
		if (m_pVecBaseNode[i]->getId() == pNode->getId())
		{
			m_pVecBaseNode.remove(i);
			break;
		}
	}
}

void CMeasurePoint::setAlarmPoint(bool bAlarm)
{
	m_bAlarmPoint = bAlarm;
}

void CMeasurePoint::setStatus(EPointQuality status) 
{
	m_eStatus = status;
}

void CMeasurePoint::setUnit(const QString& unit) 
{
	m_sUnit = unit;
}

void CMeasurePoint::setValue(const QVariant& value) 
{
	if (isValidValue(value)) 
	{
		m_eStatus = EPointQuality::enGood;
		QWriteLocker locker(&m_rwLock);
		m_vValue = value;
		m_lastUpdateTime = QDateTime::currentDateTime();
		//updateData();
	}
}

void CMeasurePoint::setValue(const QVariant & value, const QString & fileRef)
{
	if (isValidValue(value))
	{
		m_eStatus = EPointQuality::enGood;
		QWriteLocker locker(&m_rwLock);
		m_vValue = value;
		m_lastUpdateTime = QDateTime::currentDateTime();
		if (fileRef != "")
		{
			m_sFileRef = fileRef;
		}
		//updateData();
	}
}

void CMeasurePoint::setMappedAddr(QString & sMappedAddr)
{
	m_sMappedAddr = sMappedAddr;
}



void CMeasurePoint::initPoint()
{
	switch (m_eType) {
	case EPointType::enAnalog:
		m_sValType = "Analog";
		break;

	case EPointType::enDigital:
		m_sValType = "Digital";
		break;

	case EPointType::enEnum:
		m_sValType = "Enum";
		break;

	case EPointType::enString:
		m_sValType = "String";
		break;

	case EPointType::enBitMask:
		m_sValType = "BitMask";
		break;

	case EPointType::enFileRef:
		m_sValType = "FileRef";
		break;

	default:
		m_sValType = "Analog";
	}
	m_lastUpdateTime = QDateTime::currentDateTime();
}



bool CMeasurePoint::isValidValue(const QVariant& value) const
{
	switch (m_eType) {
	case EPointType::enAnalog:
		// 对于模拟量类型，值应在某个有效范围内
		if (value.type() == QVariant::Double)
		{
			double val = value.toDouble();
			return true; // 示例：模拟量在 0 到 100 范围内有效
		}
		else if(value.type() == QVariant::Int) 
		{
			double val = value.toInt();
			return true; // 示例：模拟量在 0 到 100 范围内有效
		}
		break;

	case EPointType::enDigital:
		// 对于数字量类型，值应该是 true 或 false
		if (value.type() == QVariant::Bool) {
			return true;
		}
		break;

	case EPointType::enEnum:
		// 对于枚举量，值应该是一个合法的枚举值
		// 假设枚举类型为 `enum`，可以根据实际需要定义合法值
		if (value.type() == QVariant::Int) {
			int enumValue = value.toInt();
			// 假设枚举值应该在 [0, 1, 2] 之间
			return (enumValue >= 0 && enumValue <= 2);
		}
		break;

	case EPointType::enString:
		// 对于字符串类型，值不能为空
		if (value.type() == QVariant::String) 
		{
			return !value.toString().isEmpty();
		}
		break;

	case EPointType::enBitMask:
		// 对于位标志类型，值应为 0 或 1
		if (value.type() == QVariant::Int) {
			int bitValue = value.toInt();
			return (bitValue == 0 || bitValue == 1);
		}
		break;

	case EPointType::enFileRef:
		// 对于图像引用类型，值应为有效的图像路径（非空字符串）
		if (value.type() == QVariant::String) {
			QString path = value.toString();
			return !path.isEmpty() && QFileInfo::exists(path);  // 检查文件是否存在
		}
		break;

	default:
		return false; // 默认返回 false，表示无效
	}
	return false; // 如果没有匹配的类型或值不符合要求
}

